在 React 要渲染一個Array時,如果沒有在每一個被渲染的元件加上 key 這個 prop,就會跳出 Warning: Each child in a list should have a unique “key” prop.
這個錯誤訊息。
為什麼要有key?
原因是在React列表中的每一個元素都需要有一個獨特的key,這個key會幫助React用來判別元素是否要執行「新增、刪除、修改」。
例如上方範例圖片中,有三個不同顏色的圓圈,要將圓圈順序改為(紅->藍->黃),可能有幾種方法可以達成
如果沒有為每一個圓圈加上獨特的key,那麼會無法辨別會是使用哪一種方法來達到結果
假如這些圓圈都各自有自己的狀態,比如藍色圓圈是要被選取的狀態,如果經過位置的交換,正常來說是要隨著藍色圓圈變動到中間的位置,React進行重新渲染時,中間位置的藍色圓圈要保持選取狀態,那如果沒有幫他們加上key,React會無法辨識,可能就會產生BUG
為什麼index不能當作key來使用?
因為index在瀏覽器的順序固定是[0,1,2,...],將元素的key設定為index,如果這些元素都帶有狀態,假設上方圖片中的圓圈在index=0
的位置插入粉紅色的圓圈,實際上狀態應該是要跟在原本的index=0
紅色圓圈,當元素的順序變化時,key 會跟著變,紅色圓圈變為index=1
,React 就無法正確辨識哪個項目是新增的,哪個是移動的,哪個是未改變的,使元件與狀態產生不協調。
再舉一個程式碼例子
//這個例子中,如果 todos 列表的項目被重新排序,則每個項目的 key 仍然保持不變(因為 index 沒有改變)。可能會導致渲染和狀態更新的問題
const todoItems = todos.map((todo, index) =>
// 不應該使用index索引作為 key
<li key={index}>
{todo.text}
</li>
);
//將key改成唯一識別的id,即使 todos 列表的項目被重新排序,每個項目的 key 也都是唯一的和穩定的,這有助於確保每個項目的渲染和狀態正確
const todoItems = todos.map((todo) =>
// 可以改使用 todo 的 id 作為 key
<li key={todo.id}>
{todo.text}
</li>
);
總結來說,如果元素的順序有可能改變,那麼使用 index 作為 key 會比較不建議
如果列表是靜態的且不會改變,則可以使用 index 作為 key,但為了確保程式的穩定性和可維護性,最好還是使用一個唯一且穩定的屬性(如 id)作為 key
參考資料
圖片來源
為什麼 React 渲染列表時需要加上 key?
I Want To Know React - 初探 Key